<?php

declare(strict_types=1);

namespace App\Resource\Service\Navigation;


use App\Common\Service\BaseService;
use App\Resource\Model\CrdNavigationModel;
use App\Resource\Model\CrdNavigationShopModel;
use App\Resource\Model\NavigationModel;
use App\Resource\Model\NavigationShopModel;

class NavigationBaseService extends BaseService
{

    /**
     * 小程序获取首页导航数据
     * @param int $shop_id
     * @param int $shopType
     * @return array
     * @author ran
     * @date 2021-03-20 11:18
     * mailbox 466180170@qq.com
     */
    public function getNavList($shop_id = 0, $shopType = 0)
    {
        $result = [];
        $resultKey = $this->getKeysFunc($shop_id);
        $needBindShop = [NavigationModel::TYPE_POPUP, NavigationModel::TYPE_PLAY_IMAGE];
        $prefix = $shopType == 1 ? 'crd' : 'jsd';
        for ($i = 1; $i < 7; $i++) {
            if ($resultKey[$i]) {
                $key = "{$prefix}:nav:{$i}";
                $hashKey = !in_array($i, $needBindShop) ? 'list' : (string)$shop_id;
                $result[$resultKey[$i]['key']] = $this->hashGet(function ($model) use ($i, $resultKey) {
                    return $resultKey[$i]['callback']($model, $i);
                }, $hashKey, $key, $shopType);
            }
        }
        return $result;
    }

    /**
     * 获取首页的 redis 数据集合的 key 和查询条件等
     * @param $shop_id
     * @return array
     * @author ran
     * @date 2021-03-20 11:18
     * mailbox 466180170@qq.com
     */
    public function getKeysFunc($shop_id)
    {
        $where = function ($q) use ($shop_id) {
            $nav_ids = $this->getShopNavigationIds($shop_id);
            $q->whereIn('id', $nav_ids);
            $q->where('start_time', '<', date('Y-m-d H:i:s'));
            $q->where('end_time', '>', date('Y-m-d H:i:s'));
        };
        return [
            '',
            [
                'key'      => 'nav_list',
                'callback' => function ($model, $typeIndex) {
                    $field = ['id', 'title', 'img', 'created_at', 'jump_type', 'jump_url', 'sort', 'end_time'];
                    return $model->select($field)->where('type', $typeIndex)->orderBy('sort', 'desc')->limit(10);
                },
            ],
            [
                'key'      => 'banner_list',
                'callback' => function ($model, $typeIndex) use ($where) {
                    $field = ['id', 'title', 'img', 'created_at', 'jump_type', 'jump_url', 'sort', 'end_time'];
                    return $model->select($field)
                        ->where($where)
                        ->where('type', $typeIndex)
                        ->orderBy('sort', 'desc')
                        ->limit(10);
                },
            ],
            [
                'key'      => 'popup_list',
                'callback' => function ($model, $typeIndex) use ($where) {
                    $field = ['id', 'title', 'img', 'created_at', 'jump_type', 'jump_url', 'sort', 'end_time'];
                    return $model->select($field)
                        ->where($where)
                        ->where('type', $typeIndex)
                        ->orderBy('sort', 'desc')
                        ->limit(10);
                },
            ],
            [
                'key'      => 'notice_list',
                'callback' => function ($model, $typeIndex) {
                    $field = ['id', 'title', 'img', 'created_at', 'jump_type', 'jump_url', 'sort', 'end_time'];
                    return $model->select($field)
                        ->where('status', 1)
                        ->where('type', $typeIndex)
                        ->orderBy('sort', 'desc')
                        ->limit(10);
                },
            ],
            [
                'key'      => 'landing_list',
                'callback' => function ($model, $typeIndex) {
                    $field = ['id', 'title', 'img', 'created_at', 'jump_type', 'jump_url', 'sort', 'end_time'];
                    return $model->select($field)->where('type', $typeIndex)->orderBy('sort', 'desc')->limit(10);
                },
            ],
            [
                'key'      => 'coupon_image',
                'callback' => function ($model, $typeIndex) {
                    $field = ['id', 'title', 'img', 'created_at', 'jump_type', 'jump_url', 'sort', 'end_time'];
                    return $model->select($field)->where('type', $typeIndex)->orderBy('sort', 'desc')->limit(10);
                },
            ],
        ];
    }

    /**
     * 获取指定商家的导航id数组
     * @param $shop_id
     * @param false $isNextDay
     * @return array
     * @author ran
     * @date 2021-03-20 11:18
     * mailbox 466180170@qq.com
     */
    public function getShopNavigationIds($shop_id, $isNextDay = false): array
    {
        $model = $isNextDay ? CrdNavigationShopModel::query() : NavigationShopModel::query();
        $ids = $model->where('shop_id', $shop_id)->pluck('navigation_id');
        return $ids ? $ids->toArray() : [];
    }

    /**
     * 获取 hash 值
     *
     * @param $func
     * @param string $hashKey
     * @param string $key
     * @param $shopType
     * @return array|mixed
     */
    public function hashGet($func, string $hashKey, string $key = 'resource', $shopType = 0)
    {
        if ($data = $this->hGetToArray($key, $hashKey)) {
            return $data;
        }
        $list = $func($shopType === 1 ? CrdNavigationModel::query() : NavigationModel::query())->get();
        if (!count($list)) {
            return [];
        }
        $this->resourceRedis->hSet($key, $hashKey, $list->toJson());
        $this->setExpireByTime($list, $key);
        return $this->hGetToArray($key, $hashKey);
    }

    /**
     * 通过最小的过期时间设置过期
     * @param $list
     * @param $key
     * @author ran
     * @date 2021-03-20 11:22
     * mailbox 466180170@qq.com
     */
    public function setExpireByTime($list, $key)
    {
        // 过滤掉未设置过期时间的
        if ($list = array_filter(array_column($list->toArray(), 'end_time'))) {
            $ttl = strtotime(min($list));
            $ttl > time() && $this->resourceRedis->expireAt($key, $ttl);
        }
    }

    /**
     * 转换 hash 类型
     * @param $key
     * @param $hashKey
     * @return mixed
     * @author ran
     * @date 2021-03-20 11:22
     * mailbox 466180170@qq.com
     */
    public function hGetToArray($key, $hashKey)
    {
        $result = $this->resourceRedis->hGet($key, $hashKey);
        !$result && $result = '{}';
        return json_decode($result, true);
    }

}